using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Tarkin.InfrastructureLibrary.Utilities.Collections;
using NUnit.Framework;

namespace Tarkin.InfrastructureLibrary.Tests.Utilities.Collections
{
    /// <summary>
    /// SetTests is the NUnit TestFixture for the Tarkin.InfrastructureLibrary.Utilities.Collections.Set class.
    /// </summary>
    [TestFixture]
    public class SetTests
    {
        [Test]
        public void TestDefaultConstructor ()
        {
            Set < StringBuilder > set = new Set < StringBuilder > ();

            Assert.IsNotNull ( set );
        }

        [Test]
        public void TestOverloadedConstructor ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );

            Assert.IsTrue ( set.Contains ( setObject ) );
        }

        [Test]
        public void TestCountProperty ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );

            Assert.AreEqual ( 1, set.Count );
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void TestAddMethodNullObject ()
        {
            Set < StringBuilder > set = new Set < StringBuilder > ();

            set.Add ( null );
        }

        [Test]
        [ExpectedException ( typeof ( ArgumentException ) )]
        public void TestAddMethodDuplicateObject ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );

            set.Add ( setObject );
        }

        [Test]
        public void TestClearMethod ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );

            set.Clear ();

            Assert.AreEqual ( 0, set.Count );
        }

        [Test]
        public void TestContainsMethod ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );

            Assert.IsTrue ( set.Contains ( setObject ) );
        }

        [Test]
        public void TestCopyToMethodOneParameter ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );
            StringBuilder [] array = new StringBuilder [ 1 ];

            set.CopyTo ( array );

            Assert.AreEqual ( setObject, array [ 0 ] );
        }

        [Test]
        public void TestCopyToMethodTwoParameters ()
        {
            StringBuilder setObject = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject );
            StringBuilder [] array = new StringBuilder [ 3 ];

            set.CopyTo ( array, 1 );

            Assert.AreEqual ( setObject, array [ 1 ] );
        }

        [Test]
        public void TestCopyToMethodFourParameters ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );
            StringBuilder [] array = new StringBuilder [ 3 ];

            set.Add ( setObject2 );
            set.Add ( setObject3 );

            set.CopyTo ( 1, array, 1, 1 );

            Assert.AreEqual ( setObject2, array [ 1 ] );
        }

        [Test]
        public void TestRemoveMethod ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );

            set.Add ( setObject2 );
            set.Add ( setObject3 );

            set.Remove ( setObject2 );

            Assert.AreEqual ( 2, set.Count );
        }

        [Test]
        public void TestGetEnumeratorMethodGeneric ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder>  set = new Set < StringBuilder > ( setObject1 );
            IEnumerator < StringBuilder > enumerator = set.GetEnumerator ();

            enumerator.MoveNext ();

            Assert.AreEqual ( setObject1, enumerator.Current );
        }

        [Test]
        public void TestGetEnumeratorMethod ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );
            IEnumerator enumerator = ((IEnumerable)set).GetEnumerator ();

            enumerator.MoveNext ();

            Assert.AreEqual ( setObject1, (StringBuilder)enumerator.Current );
        }

        [Test]
        public void TestAddAllMethod ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            List < StringBuilder > list = new List < StringBuilder > ();
            Set < StringBuilder > set = new Set < StringBuilder > ();

            list.Add ( setObject1 );
            list.Add ( setObject2 );
            list.Add ( setObject3 );

            set.AddAll ( list );

            Assert.AreEqual ( 3, set.Count );
        }

        [Test]
        public void TestContainsAllMethodTrue ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            List < StringBuilder > list = new List < StringBuilder > ();
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );

            set.Add ( setObject2 );
            set.Add ( setObject3 );

            list.Add ( setObject1 );
            list.Add ( setObject2 );
            list.Add ( setObject3 );

            Assert.IsTrue ( set.ContainsAll ( list ) );
        }

        [Test]
        public void TestContainsAllMethodFalse ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            List < StringBuilder > list = new List < StringBuilder > ();
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );

            set.Add ( setObject3 );

            list.Add ( setObject1 );
            list.Add ( setObject2 );
            list.Add ( setObject3 );

            Assert.IsFalse ( set.ContainsAll ( list ) );
        }

        [Test]
        public void TestRemoveAllMethod ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            List < StringBuilder > list = new List < StringBuilder > ();
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );

            set.Add ( setObject2 );
            set.Add ( setObject3 );

            list.Add ( setObject1 );
            list.Add ( setObject2 );

            set.RemoveAll ( list );

            Assert.AreEqual ( 1, set.Count );
            Assert.IsTrue ( set.Contains ( setObject3 ) );
        }

        [Test]
        public void TestRetainAllMethod ()
        {
            StringBuilder setObject1 = new StringBuilder ( "Hello, World!" );
            StringBuilder setObject2 = new StringBuilder ( "Aloha" );
            StringBuilder setObject3 = new StringBuilder ( "Guten Abend" );
            List < StringBuilder > list = new List < StringBuilder > ();
            Set < StringBuilder > set = new Set < StringBuilder > ( setObject1 );

            set.Add ( setObject2 );
            set.Add ( setObject3 );

            list.Add ( setObject1 );
            list.Add ( setObject2 );

            set.RetainAll ( list );

            Assert.AreEqual ( 2, set.Count );
            Assert.IsTrue ( set.Contains ( setObject1 ) );
            Assert.IsTrue ( set.Contains ( setObject2 ) );
        }

        [Test]
        public void TestIsReadOnlyProperty ()
        {
            Set < string > set = new Set < string > ();

            Assert.AreEqual ( false, set.IsReadOnly );
        }
    }
}
